缓存雪崩
当大量缓存在同一时间失效或者过期,亦或者Redis故障宕机时,如果此时有大量用户数据访问,Redis 无法处理,于是全部请求都会直接访问数据库,导致数据库压力剧增,严重会导致数据库宕机,从而出现更严重的问题
常见解决方法:
- 给各数据设置不相同的过期时间,尽量让他们不要在同一时间过期
- 设置互斥锁,当发现需要查找的数据在Redis中找不到,就加上一个互斥锁,保证一个时间只有规定的次数查询数据库来构建缓存
- 如果是宕机,那我们可以用熔断来解决,或者是拒绝服务
缓存击穿
缓存击穿跟缓存雪崩很相似,可以认为缓存击穿是缓存雪崩其中之一
如果缓存中某个热点数据过期了,此时大量的数据请求访问了该数据,就无法从缓存中读取,直接访问数据库,数据库很容易被高并发的请求冲垮,这就是缓存击穿问题。
常见解决方法:
- 互斥锁方案,保证同一时间只有一个业务线程更新缓存
- 不给热点数据设置过期时间,由后台异步更新缓存,或者在热点数据准备要过期前,提前通知后台线程更新缓存以及重新设置过期时间;
缓存穿透
当用户访问的数据不存在,导致请求在访问缓存时,发现缓存缺失,再去访问数据库时,发现数据库中也没有要访问的数据,那么此时大量的请求都落在数据库中,导致数据库压力骤增
常见解决方法
- 限制非法请求,进行参数校验,对于不合法的参数请求直接抛出异常返回给客户端。
- 缓存空值或者默认值,当发现缓存穿透的现象时,可以针对查询的数据,在缓存中设置一个空值或者默认值,这样后续请求就可以从缓存中读取到空值或者默认值,返回给应用,使其不会继续查询数据库
- 使用布隆过滤器,过滤器说数据不存在,那么数据库中一定不会有这个数据。如果说数据存在,并不一定证明数据库中存在这个数据,有误判的几率,只不过几率非常小。(底层是hash,有极小概率误判)